#ifndef _affine_h_
#define _affine_h_

#include <blitz/tinymat.h>
#include <blitz/tinyvec-et.h>
#include <blitz/matrix.h>

namespace affine2d {
	BZ_USING_NAMESPACE(blitz)
	template<typename T>
	inline void identity(TinyMatrix<T,3,3> &_matrix){
		_matrix = T(1.0), T(0.0), T(0.0), T(0.0), T(1.0), 
		T(0.0), T(0.0), T(0.0), T(1.0);
	}
	
	template<typename T>
	inline void scale(TinyMatrix<T,3,3> &_matrix, T sx, T sy){
		_matrix(0, 0) *= sx; _matrix(0, 1) *= sx; _matrix(0, 2) *= sx;
		_matrix(1, 0) *= sy; _matrix(1, 1) *= sy; _matrix(1, 2) *= sy;
	}
	
	template<typename T>
	inline void translate(TinyMatrix<T,3,3> &_matrix, T tx, T ty){
		_matrix(0, 2) += tx;
		_matrix(1, 2) += ty;
	}
	template<typename T>
	inline void rotate(TinyMatrix<T,3,3> &_matrix, T angle) {
		TinyMatrix<T,3,3> C;
		
		angle = (angle / 180.0) * M_PI;
		double cosa = cos(angle),
		sina = sin(angle);
		
		// Create the principal rotation matrix C_3(alpha)
		C = cosa, -sina,   0.0,
		sina,  cosa,   0.0,
		0.0,   0.0,   1.0;
		TinyMatrix<T,3,3> tmp = _matrix;
		_matrix = product(C, tmp);
	}
	
};
namespace affine {
	typedef blitz::TinyMatrix<float,3,3> transform2d;
	typedef blitz::TinyVector<float, 3> affine_point2d_t;
};

inline affine::affine_point2d_t operator*(const affine::transform2d &_matrix, affine::affine_point2d_t pt) {
	return blitz::product(_matrix, pt);
}



template <int N, int degree>
class CcircleArc
{
public:
	typedef blitz::TinyVector<float, 2> point_t;
	CcircleArc(point_t a, point_t b) {
		point_t pt, tmp;
		tmp = (b - a)/2;
		
		float angle = (-degree / 180.0) * M_PI;
		double cosa = cos(angle);
		double sina = sin(angle);
		pt = tmp[0] * cosa - tmp[1]*sina, tmp[0] * sina + tmp[1] * cosa;
		pt = pt * fabs(1 / sina);
		pt += a;
		point_t r = a - pt;
		for(int i = 0; i < N; i++) {
			angle = (-(degree *2 *i) / (180.0 * (N-1))) * M_PI;
			cosa = cos(angle),
			sina = sin(angle);
			m_pt[i] = r[0] * cosa - r[1]*sina, r[0] * sina + r[1] * cosa;
			m_pt[i] += pt;
		}
		
	}

	point_t m_pt[N];
};

//CcircleArc<10, 45>::point_t a, b;
//a = 0, 0;
//b = 0, 10;
//CcircleArc<10, 45> tmp(a, b);



#endif // _affine_h_